import format from '@/tools/format';
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';

import Loading from '@/components/loading';
import type { RequestConfig, Response, UseAxiosResponse } from './type';

const requestWrapper = async <T = any>(
  config: RequestConfig,
  request: () => Promise<AxiosResponse<Response<T>>>,
): Promise<UseAxiosResponse<T>> => {
  let msg = '';
  let response: AxiosResponse<Response<T>>;
  const { skipLoading = true } = config ?? {};
  if (!skipLoading) {
    Loading.show();
  }
  try {
    response = await request();
    return { ...response.data, response };
  } catch (e) {
    console.log(e?.toString?.(), e);
    msg = e?.response?.data?.msg ?? 'System error';
    response = e?.response;
  } finally {
    if (!skipLoading) {
      Loading.hide();
    }
  }
  return {
    success: false,
    msg,
    status: response?.status,
    response,
  };
};

export const useGet = <T = any>(url, config?: RequestConfig) =>
  requestWrapper(config, () => axios.get<Response<T>>(url, config));

export const usePost = <T = any>(
  url: string,
  data?,
  config?: RequestConfig,
  formatParams?: {
    ignoreKeyList?: Array<string>;
  },
) =>
  requestWrapper(config, () =>
    axios.post<Response<T>>(
      url,
      formatParams
        ? format.objArgsToBigCamelCase(data, formatParams?.ignoreKeyList)
        : data,
      config,
    ),
  );

export const usePut = <T = any>(
  url: string,
  data?,
  config?: RequestConfig,
  formatParams?: {
    notUseParamsToTitleCase?: boolean;
    ignoreKeyList?: Array<string>;
  },
) =>
  requestWrapper(config, () =>
    axios.put<Response<T>>(
      url,
      formatParams
        ? format.objArgsToBigCamelCase(data, formatParams?.ignoreKeyList)
        : data,
      config,
    ),
  );

export const useDelete = <T = any>(url: string, config?: RequestConfig) =>
  requestWrapper(config, () => axios.delete<Response<T>>(url, config));
